"""
智能体链

这个模块实现了一个功能完整的LangChain Agent，
展示了如何集成和使用各种工具来完成复杂任务。
"""

import logging
from typing import List, Dict, Any, Optional
from langchain.agents import create_openai_tools_agent, AgentExecutor
from langchain.agents import initialize_agent, AgentType
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage, AIMessage

from core.llm_manager import llm_manager
from core.tools_manager import tool_manager
from config.settings import settings

logger = logging.getLogger(__name__)

class SmartAgent:
    """
    智能体类
    
    集成了多种工具的智能代理，能够：
    - 理解用户意图
    - 选择合适的工具
    - 执行复杂的多步骤任务
    - 提供详细的执行过程说明
    """
    
    def __init__(self):
        """初始化智能体"""
        self.llm = None
        self.tools = []
        self.agent = None
        self.agent_executor = None
        self._initialize_agent()
        self.max_iterations: int = 5
    
    def _initialize_agent(self):
        """初始化智能体"""
        try:
            # 获取LLM
            self.llm = llm_manager.get_current_model()
            if not self.llm:
                raise Exception("没有可用的LLM模型")
            
            # 获取所有工具
            self.tools = tool_manager.get_all_tools()
            if not self.tools:
                logger.warning("没有可用的工具")
                return
            
            # 创建提示模板
            system_prompt = """你是一个功能强大的AI助手，可以使用多种工具来帮助用户解决问题。

工具使用原则：
1. 仔细分析用户的需求
2. 选择最合适的工具
3. 按步骤执行任务
4. 清楚地解释你的思考过程
5. 提供详细和准确的结果

当你需要使用工具时，请详细说明：
- 为什么选择这个工具
- 你期望得到什么结果
- 如何使用这个结果来回答用户的问题

请用中文回答所有问题。"""

            prompt = ChatPromptTemplate.from_messages([
                ("system", system_prompt),
                MessagesPlaceholder("chat_history", optional=True),
                ("human", "{input}"),
                MessagesPlaceholder("agent_scratchpad")
            ])
            
            # 创建Agent
            try:
                # 尝试使用新的OpenAI工具agent
                self.agent = create_openai_tools_agent(
                    llm=self.llm,
                    tools=self.tools,
                    prompt=prompt
                )
                
                self.agent_executor = AgentExecutor(
                    agent=self.agent,
                    tools=self.tools,
                    verbose=True,
                    handle_parsing_errors=True,
                    max_iterations=3
                )
                
            except Exception as e:
                logger.warning(f"创建OpenAI工具agent失败，尝试使用传统agent: {str(e)}")
                
                # 回退到传统的agent
                self.agent_executor = initialize_agent(
                    tools=self.tools,
                    llm=self.llm,
                    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
                    verbose=True,
                    handle_parsing_errors=True,
                    max_iterations=3
                )
            
            logger.info(f"智能体初始化成功，已加载 {len(self.tools)} 个工具")
            
        except Exception as e:
            logger.error(f"智能体初始化失败: {str(e)}")
            self.agent_executor = None
    
    def run(self, user_input: str, chat_history: Optional[List] = None) -> str:
        """
        运行智能体
        
        Args:
            user_input (str): 用户输入
            chat_history (Optional[List]): 聊天历史
            
        Returns:
            str: 智能体响应
        """
        if not self.agent_executor:
            return "错误：智能体未正确初始化"
        
        try:
            # 准备输入
            inputs = {
                "input": user_input,
                "chat_history": chat_history or []
            }
            
            # 执行智能体
            result = self.agent_executor.invoke(inputs)
            
            # 返回结果
            if isinstance(result, dict):
                return result.get("output", str(result))
            else:
                return str(result)
                
        except Exception as e:
            error_msg = f"智能体执行错误: {str(e)}"
            logger.error(error_msg)
            return error_msg
    
    def get_available_tools(self) -> List[str]:
        """获取可用工具列表"""
        return [tool.name for tool in self.tools]
    
    def get_tool_descriptions(self) -> Dict[str, str]:
        """获取工具描述"""
        return {tool.name: tool.description for tool in self.tools}
    
    def is_ready(self) -> bool:
        """检查智能体是否准备就绪"""
        return self.agent_executor is not None

class ToolDemoAgent:
    """
    工具演示智能体
    
    专门用于演示各种工具的使用方法和原理
    """
    
    def __init__(self):
        """初始化演示智能体"""
        self.llm = llm_manager.get_current_model()
        self.tools_info = tool_manager.get_tool_info()
    
    def demo_tool_usage(self, tool_name: str, example_input: str = None) -> Dict[str, Any]:
        """
        演示特定工具的使用
        
        Args:
            tool_name (str): 工具名称
            example_input (str): 示例输入
            
        Returns:
            Dict[str, Any]: 演示结果
        """
        try:
            tool = tool_manager.get_tool(tool_name)
            if not tool:
                return {
                    "success": False,
                    "error": f"工具 '{tool_name}' 不存在"
                }
            
            # 工具信息
            tool_info = {
                "name": tool.name,
                "description": tool.description,
                "type": "LangChain Tool"
            }
            
            # 如果提供了示例输入，执行工具
            result = None
            if example_input:
                try:
                    result = tool.run(example_input)
                except Exception as e:
                    result = f"执行错误: {str(e)}"
            
            return {
                "success": True,
                "tool_info": tool_info,
                "example_input": example_input,
                "result": result,
                "usage_tips": self._get_usage_tips(tool_name)
            }
            
        except Exception as e:
            return {
                "success": False,
                "error": f"演示工具失败: {str(e)}"
            }
    
    def _get_usage_tips(self, tool_name: str) -> List[str]:
        """获取工具使用提示"""
        tips_map = {
            "duckduckgo_search": [
                "输入简洁的搜索关键词",
                "使用英文搜索通常能获得更好的结果",
                "可以搜索最新的新闻和信息"
            ],
            "calculator": [
                "支持基础数学运算：+、-、*、/",
                "支持括号和浮点数",
                "示例：'2+2'、'(10*5)/2'、'3.14*2'"
            ],
            "current_time": [
                "不需要输入参数或输入格式类型",
                "支持的格式：'date'、'time'、'full'",
                "默认返回中文格式的完整时间"
            ],
            "document_summary": [
                "输入需要摘要的长文本",
                "适用于文章、报告等文档",
                "会提取前几句作为摘要"
            ]
        }
        
        return tips_map.get(tool_name, ["按照工具描述使用即可"])
    
    def list_all_tools(self) -> Dict[str, Any]:
        """列出所有可用工具"""
        return {
            "total_count": self.tools_info["total_tools"],
            "tools": [
                {
                    "name": name,
                    "description": desc,
                    "available": tool_manager.is_tool_available(name)
                }
                for name, desc in self.tools_info["tool_descriptions"].items()
            ]
        }

# 创建全局智能体实例
smart_agent = SmartAgent()
tool_demo_agent = ToolDemoAgent() 